'''
Created on Oct 6, 2012

@author: shraybansal
'''
import numpy as np
from math import sqrt

def euclOne(features1, features2):
    #return np.linalg.norm(np.subtract(features1, features2), 2)
    return sqrt((features1 - features2)*(features1 - features2))

def eucl(features1, features2):
    dist = 0.0
    dim = len(features1)
    for i in range(0, dim):
        dist += pow(features1[i] - features2[i], 2)
    return sqrt(dist) 

def DTW (query, ground_truth):
    n = len(query)
    m = len(ground_truth)
    
    win =63#125
    win = max(win, abs(n-m))
    
    warp_mat = np.zeros(shape = (n + 1, m + 1))
    
    for i in range(n+1):
        for j in range(m+1):
            warp_mat[i][j] = float('inf')
            
    warp_mat[0][0] = 0.0

    for i in range(1, n + 1):
        for j in range(1, m + 1):
            if (j>max(0,i-win) and j<min(m+1,i+win)):
                dist = eucl(query[i - 1], ground_truth[j - 1])
                
                warp_mat[i][j] = dist + min(warp_mat[i][j-1], warp_mat[i-1][j-1], warp_mat[i-1][j])
                
    return warp_mat[n][m]

def DTWOne (query, ground_truth):
    n = len(query)
    m = len(ground_truth)
    
    win =63#125
    win = max(win, abs(n-m)+1)
        
    warp_mat = np.zeros(shape = (n + 1, m + 1))
    
    for i in range(n+1):
        for j in range(m+1):
            warp_mat[i][j] = float('inf')
            
    warp_mat[0][0] = 0.0
    
  

    for i in range(1, n + 1):
        infiCount=True
        for j in range(1, m + 1):
            if (j>max(0,i-win) and j<min(m+1,i+win)):
                dist = euclOne(query[i - 1], ground_truth[j - 1])
                warp_mat[i][j] = dist + min(warp_mat[i][j-1], warp_mat[i-1][j-1], warp_mat[i-1][j])
#                if not warp_mat[i][j] =='inf':
                infiCount=False
        if infiCount:
            print 'i=',i,'j=',j
            
    return warp_mat[n][m]